package aex.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.ParameterizedType;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.UUID;

import javax.imageio.ImageIO;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.ImageIcon;

import org.apache.struts2.ServletActionContext;

import cn.itcast.mail.Mail;
import cn.itcast.mail.MailUtils;

/**
 * 常用工具类
 * 
 * @author JiangYouYao
 */
public class CU {

	public static final String CODE = "1";
	public static final String IMAGE = "2";

	/**
	 * 干扰线的类型【正常 无】
	 */
	public static final int UPSETTYPE_NORMAL = 1;
	/**
	 * 干扰线的类型【简单】
	 */
	public static final int UPSETTYPE_SIMPLE = 2;
	/**
	 * 干扰线的类型【复杂】
	 */
	public static final int UPSETTYPE_COMPLEX = 3;

	private static Color colors[] = { Color.black, Color.blue, Color.cyan,
			Color.gray, Color.green, Color.magenta, Color.orange, Color.pink,
			Color.red, Color.yellow };

	/**
	 * @Description: 获得该类的泛型类型
	 * @param Class
	 * @Return: Class 泛型的类型
	 * @Author: JiangYouYao
	 * @Version: V1.00 （版本号1.0)
	 * @Create Date: 2014-8-12 （创建日期）
	 */
	@SuppressWarnings("rawtypes")
	public static Class getClass(Class clazz) {
		// 泛型转换
		ParameterizedType pt = (ParameterizedType) clazz.getGenericSuperclass();
		return (Class) pt.getActualTypeArguments()[0];
	}

	/**
	 * @Description: 在内存中创建一张验证码图片，可以指定背景图片。字体，大小。是否绘制干扰线。
	 * @param backgroundImagePath
	 *            背景图片的路径
	 * @param font
	 *            字体
	 * @param width
	 *            图片的宽度
	 * @param height
	 *            图片的高度
	 * @param upsetType
	 *            干扰线类型
	 * @param count
	 *            验证码字数
	 * @return Map<String, Object> 返回2个值 第一个是BufferImage，第二个是Code<BR>
	 *         使用常量分别取出这里的值。[CODE] [IMAGE]
	 * @Author: JiangYouYao
	 * @Version: V1.00 （版本号1.0)
	 * @Create Date: 2014-9-1 （创建日期）
	 */

	public static Map<String, Object> getVerificationCode(
			String backgroundImagePath, Font font, int width, int height,
			int upsetType, int count) {
		Map<String, Object> map = new HashMap<String, Object>();

		int fontSize = font.getSize();
		// top值表示文字的底部离图片顶部的高度
		int top = (height - fontSize) / 2 + fontSize;
		int charWidth = (width - 20) / count;
		int left = 5;

		StringBuilder code = new StringBuilder();

		BufferedImage image = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_BGR);
		// 2.在图片上写数据
		Graphics g = image.getGraphics();

		g.setFont(font);

		// 绘制背景图
		CU.deBugPrintln(backgroundImagePath);
		g.drawImage(new ImageIcon(backgroundImagePath).getImage(), 0, 0, width,
				height, null);

		if (upsetType == UPSETTYPE_COMPLEX) {
			g.setColor(Color.black);

			int[] x = new int[height];

			int dis = width / height + 1;

			int[] y = new int[height];
			for (int i = 0; i < x.length; i++) {
				if (i > 0) {
					x[i] = x[i - 1] + dis;
				} else {
					x[i] = dis;
				}
				y[i] = (int) (Math.sin(i) * height);
			}
			g.drawPolyline(x, y, x.length);

			for (int i = 0; i < x.length; i++) {
				if (i > 0) {
					y[i] = y[i - 1] + dis;
				} else {
					y[i] = dis;
				}
				x[i] = (int) (Math.sin(i) * width);
			}
			g.drawPolyline(x, y, x.length);

		} else if (upsetType == UPSETTYPE_SIMPLE) {
			g.setColor(Color.black);
			int[] x = new int[height];

			int dis = width / height * 4;

			int[] y = new int[height];
			for (int i = 0; i < x.length; i++) {
				if (i > 0) {
					x[i] = x[i - 1] + dis;
				} else {
					x[i] = dis;
				}
				y[i] = (int) (Math.sin(i) * height);
			}
			g.drawPolyline(x, y, x.length);
		}

		// 绘制字母数字
		for (int i = 0; i < count; i++) {
			g.setColor(colors[getRandomNum()]);
			if (getRandomNum() > 5) {
				int temp = getRandomNum();
				code.append(temp);
				g.drawString(temp + "", left, top);
				left += charWidth;

			} else {
				char temp = getRandomLetter();
				code.append(temp);
				g.drawString(temp + "", left, top);
				left += charWidth;
			}
		}

		map.put(CODE, code.toString());
		map.put(IMAGE, image);

		return map;
	}

	/**
	 * 开发阶段，打印调试信息，是否为开发阶段在aex-webconfig.xml中配置
	 * 
	 * @param msg
	 */
	public static void deBugPrintln(Object msg) {
		if (InitWebContex.DEBUG_ON) {
			System.out.println(msg);
		}
	}

	private static Random r = new Random();

	/**
	 * @Description: 获得一个不重复的32位的随机的大写字符串
	 * @param 无
	 * @Return:String
	 * @Author: JiangYouYao
	 * @Version: V1.00 （版本号1.0)
	 * @Create Date: 2014-8-30（创建日期）
	 */
	public static String uuid() {
		return UUID.randomUUID().toString().replace("-", "").toUpperCase();
	}

	/**
	 * @Description: 获得一个随机的字母也许是大写也许是小写
	 * @param 无
	 * @Return:char
	 * @Author: JiangYouYao
	 * @Version: V1.00 （版本号1.0)
	 * @Create Date: 2014-9-1（创建日期）
	 */
	public static char getRandomLetter() {
		int number = r.nextInt(26);
		int caseType = number > 13 ? 97 : 65;
		return (char) (number + caseType);
	}

	/**
	 * @Description: 获得一个随机的0-9的数字
	 * @param 无
	 * @Return:int
	 * @Author: JiangYouYao
	 * @Version: V1.00 （版本号1.0)
	 * @Create Date: 2014-9-1（创建日期）
	 */
	public static int getRandomNum() {

		return r.nextInt(10);
	}

	/**
	 * 获取MD5加密后的字符串对应的值
	 * 
	 * @param content
	 * @return
	 */
	public static String getMD5(String content) {
		try {
			MessageDigest digest = MessageDigest.getInstance("MD5");
			digest.update(content.getBytes());
			return getHashString(digest);

		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return null;
	}

	private static String getHashString(MessageDigest digest) {
		StringBuilder builder = new StringBuilder();
		for (byte b : digest.digest()) {
			builder.append(Integer.toHexString((b >> 4) & 0xf));
			builder.append(Integer.toHexString(b & 0xf));
		}
		return builder.toString();
	}

	/**
	 * 获取时间戳
	 * 
	 * @return
	 */
	public static String getTimeMark() {
		Calendar c = Calendar.getInstance();
		int year = c.get(Calendar.YEAR);
		int mouth = c.get(Calendar.MONTH);
		int day = c.get(Calendar.DAY_OF_MONTH);
		int hour = c.get(Calendar.HOUR_OF_DAY);
		int minute = c.get(Calendar.MINUTE);
		int second = c.get(Calendar.SECOND);
		int haomiao = c.get(Calendar.MILLISECOND);
		return "" + year + mouth + day + hour + minute + second + haomiao;
	}

	public static Timestamp getSqlTime() {
		return new Timestamp(new Date().getTime());
	}

	public static String encodingUTF(String str) {

		if (str == null) {
			return null;
		}
		try {
			str = new String(str.getBytes("ISO8859-1"), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return str;
	}

	/**
	 * 设置消息页面
	 * 
	 * @param request
	 * @param msg
	 * @param type
	 * @param url
	 * @return
	 */
	public static String goMsgPage(HttpServletRequest request, String msg,
			String type, String url) {
		request.setAttribute("msg", msg);
		request.setAttribute("type", type);
		request.setAttribute("url", url);
		return "msg";
	}

	/**
	 * 获取一个set集合中的第一个元素
	 * 
	 * @author JiangYouYao
	 * @date 2014年12月20日-上午10:03:34
	 * @param set
	 * @return
	 */
	public static <T> T getFirstElement(Set<T> set) {
		System.out.println("set=size" + set.size());
		Iterator<T> it = set.iterator();
		return it.next();
	}

	/**
	 * 图片压缩
	 * @param file
	 * @param newHeight
	 * @param newWidth
	 * @param outputDir
	 * @param outputFileName
	 */
	public static void compressionImg(File file, int newHeight, int newWidth,
			String outputDir, String outputFileName) {
		try {

			Image img = ImageIO.read(file);
			// // 判断图片格式是否正确
			BufferedImage tag = new BufferedImage(newWidth, newHeight,
					BufferedImage.TYPE_INT_RGB);
			/*
			 * Image.SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的 优先级比速度高 生成的图片质量比较好 但速度慢
			 */
			tag.getGraphics().drawImage(
					img.getScaledInstance(newWidth, newHeight,
							Image.SCALE_SMOOTH), 0, 0, null);
			FileOutputStream out = new FileOutputStream(outputDir
					+ outputFileName);
			// JPEGImageEncoder可适用于其他图片类型的转换
			ImageIO.write(tag, "jpg", out);
			out.close();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 得到几天前的时间
	 * 
	 * @param d
	 * @param day
	 * @return
	 */
	public static Timestamp getDateBefore(Date d, int day) {
		Calendar now = Calendar.getInstance();
		now.setTime(d);
		now.set(Calendar.DATE, now.get(Calendar.DATE) - day);
		return new Timestamp(now.getTime().getTime());
	}

	/**
	 * 得到几天后的时间
	 * 
	 * @param d
	 * @param day
	 * @return
	 */
	public static Timestamp getDateAfter(Date d, int day) {
		Calendar now = Calendar.getInstance();
		now.setTime(d);
		now.set(Calendar.DATE, now.get(Calendar.DATE) + day);
		return new Timestamp(now.getTime().getTime());
	}

	
	public static String getCustomerIp(HttpServletRequest request) {
		String ip = request.getRemoteAddr();
		return ip;
	}

	/**
	 * 根据图片文件路径删除文件
	 * @param phPath
	 */
	public static void delImageFile(String sPath) {
		CU.deBugPrintln(sPath);
		CU.deBugPrintln(sPath.indexOf("/admin/images/default.jpg"));
		if(sPath.indexOf("/admin/images/default.jpg")==-1){//不能把系统默认图片删除了！
			@SuppressWarnings("deprecation")
			File file = new File(ServletActionContext.getRequest().getRealPath(sPath));
			CU.deBugPrintln(file.isFile());
			if(file.isFile()){
				file.delete();
			}
			CU.deBugPrintln("文件被删除");
		}else{
			CU.deBugPrintln("系统图片不被删除");
		}
	}
	
	/**
	 * 系统接收的图片统一放在attached文件夹中，
	 * 程序中只要指明文件需要放在哪一个文件夹里面就可以把文件写入了
	 * @param file
	 * @param folder
	 * @param fileName
	 * @return
	 */
	public static String writeFile(File file,String folder,String fileName,String appName){
		@SuppressWarnings("deprecation")
		String realPath = ServletActionContext.getRequest().getRealPath(
				"/attached/"+folder);// 获取文件存储路径
		String visitedPath="";
		OutputStream os=null;
		InputStream is = null;
		String filePath="";
		try{
			// 创建文件夹
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
			String ymd = sdf.format(new Date());
			realPath += "/" + ymd + "/";
			File dirFile = new File(realPath);
			if (!dirFile.exists()) {
				dirFile.mkdirs();
			}
			//获取文件类型
			String fileType = fileName.substring(
					fileName.lastIndexOf(".") + 1, fileName.length());
			String randomName=uuid();
			filePath=realPath+randomName+"."+fileType;
			visitedPath=appName+"/attached/"+folder+ "/" + ymd + "/"+randomName+"."+fileType;;
			os = new FileOutputStream(new File(filePath));
			is = new FileInputStream(file);
			byte[] buf = new byte[1024];
			int length = 0;
			
			while (-1 != (length = is.read(buf))) {// 把图片写入硬盘
				os.write(buf, 0, length);
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			try {
				if(is!=null)
					is.close();
				if(os!=null)
					os.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return visitedPath;
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	/**
	 * 根据传入的宽高产生一个验证码图片发送到客户端，
	 * 存入session中 名称为yzm
	 * @param response
	 * @param request
	 * @param width
	 * @param height
	 */
	public static void sendVerificationCode(HttpServletResponse response,HttpServletRequest request,int width,int height) {
		response.setDateHeader("Expires", -1);
		response.setHeader("Cache-Control", "no-cache");
		response.setHeader("Pragma", "no-cache");
		// 6.通知浏览器以图片打开发过去的数据
		response.setHeader("Content-Type", "image/jpeg");
		@SuppressWarnings("rawtypes")
		Map map = CU
				.getVerificationCode(SSHUtil.getResourceRealPath(request,
						"images/yzm_bg.jpg"), new Font("Microsoft Yahei",
						Font.PLAIN, 30), width, height, CU.UPSETTYPE_COMPLEX, 4);
		CU.deBugPrintln("存入code" + map.get(CU.CODE));
		request.getSession().setAttribute("yzm", map.get(CU.CODE));
		try {
			ImageIO.write((RenderedImage) map.get(CU.IMAGE), "jpg",
					response.getOutputStream());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	

    /**
     * 向指定URL发送GET方法的请求
     * 
     * @param url
     *            发送请求的URL
     * @param param
     *            请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }
    

	/**
	 * 根据数据库中存放的日期字符串返回用户的年龄<br>
	 * 字符串格式 yyyy-MM-dd HH:mm:ss
	 * @param birthday
	 * @return
	 */
	public static String getAge(String birthday){
		
		SimpleDateFormat sdf =   new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
		String age="";
		try {
			Date date = sdf.parse(birthday);
			int year=date.getYear();
			int month=date.getMonth();
			
			Date now=new Date();
			
			int nowyear=now.getYear();
			int nowmonth=now.getMonth();
			
			int y=nowyear-year;
			int m=nowmonth-month;
			if(m>0){
				y+=1;
			}
			age=y+"";
			deBugPrintln("年龄="+y);
		} catch (ParseException e) {
			e.printStackTrace();
		}finally{
			return age;
		}
		
		
		
		
	}
	
	
	public static void SendMail(String accept,String title, String content){
		/**
		 * 1、登陆邮件服务器
		 * 服务器地址、登陆名、密码
		 * 2、创建邮件对象
		 * 发件人 * 收件人 * 主题 * 正文
		 * 3、发
		 */
		Session session=MailUtils.createSession("smtp.163.com", "18390563793@163.com", "kfoapgmrbqkinxxm");
		Mail mail=new Mail("18390563793@163.com",accept, title, content);
			try {
				MailUtils.send(session, mail);
			} catch (Exception e) {
				e.printStackTrace();
			}
	
	
	}	
	
	
}